package com.tencent.bk.devops.atom.task.util

import com.github.difflib.DiffUtils
import com.github.difflib.patch.DeltaType
import com.github.difflib.patch.Patch
import org.yaml.snakeyaml.DumperOptions
import org.yaml.snakeyaml.LoaderOptions
import org.yaml.snakeyaml.Yaml
import org.yaml.snakeyaml.constructor.SafeConstructor
import java.io.StringReader
import java.io.StringWriter

object YmlUtil {
    val options = DumperOptions().apply {
        defaultFlowStyle = DumperOptions.FlowStyle.BLOCK
        isPrettyFlow = true
        defaultScalarStyle = DumperOptions.ScalarStyle.PLAIN
        indent = 2
        indicatorIndent = 1
    }
    val yaml = Yaml(options)

//    fun mergeKeys(configKeys: List<String>): List<String> {
//        val sortedKeys = configKeys.map { it.trim() }.filter { it.isNotBlank() }.sorted()
//        val result = mutableListOf<String>()
//
//        outer@ for (key in sortedKeys) {
//            val parts = key.split(".")
//
//            // 检查是否已有更短的“父路径”存在
//            for (existing in result) {
//                val existingParts = existing.split(".")
//                if (parts.startsWith(existingParts)) {
//                    continue@outer // 当前 key 是已存在 key 的子项，跳过
//                }
//            }
//
//            result.add(key)
//        }
//
//        return result
//    }

    // 扩展函数：检查 parts 是否以 prefixParts 开头
//    private fun List<String>.startsWith(prefix: List<String>): Boolean {
//        if (this.size < prefix.size) return false
//        return this.subList(0, prefix.size) == prefix
//    }


    /**
     * 加载 YAML 文件为 Map<String, Any>
     * @param inputStream 输入流
     * @return Map<String, Any>
     */
//    fun loadYamlAsMap(inputStream: InputStream): Map<String, Any> {
//        val data: Any? = yaml.load(inputStream)
//
//        if (data !is Map<*, *>) {
//            throw IllegalArgumentException("YAML 根节点必须是 Map")
//        }
//
//        @Suppress("UNCHECKED_CAST")
//        return data as Map<String, Any>
//    }


    fun parseYamlStringToMap(yamlStr: String): Map<String, Any> {
        val yaml = Yaml()

        // 尝试第一遍解析
        val data: Any? = yaml.load(StringReader(yamlStr))


        if (data == null) {
            return emptyMap()
        }

        return when (data) {
            is Map<*, *> -> {
                @Suppress("UNCHECKED_CAST")
                data as Map<String, Any>
            }

            is String -> {
                // 情况1：字符串中包含字面 \n，说明可能是转义 YAML
                val looksLikeYaml = data.contains(":\\n") || data.contains("\\n")
                val fixed = if (looksLikeYaml) data.replace("\\n", "\n") else data

                // 再次尝试解析
                val nested: Any? = yaml.load(StringReader(fixed))
                if (nested is Map<*, *>) {
                    @Suppress("UNCHECKED_CAST")
                    nested as Map<String, Any>
                } else {
                    throw IllegalArgumentException("二次解析仍不是 Map 类型: ${nested?.javaClass?.name}")
                }
            }

            else -> throw IllegalArgumentException("YAML 根节点必须是 Map 类型，而实际是 ${data?.javaClass?.name}")
        }
    }

    // 工具：将 Map 转为 YAML 字符串
//    fun toYamlString(map: Map<String, Any>): String {
//        return yaml.dump(map)
//    }

    fun diffYamlContent(beforeYaml: String, afterYaml: String): String {
        val loaderOptions = LoaderOptions()
        val yaml = Yaml(SafeConstructor(loaderOptions))


        val oldYamlMap = yaml.load<Map<String, Any>>(beforeYaml) ?: emptyMap()

        val newYamlMap = yaml.load<Map<String, Any>>(afterYaml) ?: emptyMap()

        val formattedOld = formatYaml(oldYamlMap)
        val formattedNew = formatYaml(newYamlMap)

        val oldLines = formattedOld.lines()
        val newLines = formattedNew.lines()

        val patch: Patch<String> = DiffUtils.diff(oldLines, newLines)

        if (patch.deltas.isEmpty()) return "无变更"

        val diffResult = StringBuilder()
        for (delta in patch.deltas) {
            when (delta.type) {
                DeltaType.INSERT -> {
                    diffResult.appendLine("新增:")
                    delta.target.lines.forEach { diffResult.appendLine("+ $it") }
                }

                DeltaType.DELETE -> {
                    diffResult.appendLine("删除:")
                    delta.source.lines.forEach { diffResult.appendLine("- $it") }
                }

                DeltaType.CHANGE -> {
                    diffResult.appendLine("修改:")
                    delta.source.lines.forEach { diffResult.appendLine("- $it") }
                    delta.target.lines.forEach { diffResult.appendLine("+ $it") }
                }

                DeltaType.EQUAL -> TODO()
            }
        }

        return diffResult.toString().trimEnd()
    }

//    fun diffYamlContent(oldYamlMap: Map<String, Any>, newYamlMap: Map<String, Any>): String {
//        val formattedOld = formatYaml(oldYamlMap)
//        val formattedNew = formatYaml(newYamlMap)
//
//        val oldLines = formattedOld.lines()
//        val newLines = formattedNew.lines()
//
//        val patch: Patch<String> = DiffUtils.diff(oldLines, newLines)
//
//        if (patch.deltas.isEmpty()) return "无变更"
//
//        val diffResult = StringBuilder()
//        for (delta in patch.deltas) {
//            when (delta.type) {
//                DeltaType.INSERT -> {
//                    diffResult.appendLine("新增:")
//                    delta.target.lines.forEach { diffResult.appendLine("+ $it") }
//                }
//
//                DeltaType.DELETE -> {
//                    diffResult.appendLine("删除:")
//                    delta.source.lines.forEach { diffResult.appendLine("- $it") }
//                }
//
//                DeltaType.CHANGE -> {
//                    diffResult.appendLine("修改:")
//                    delta.source.lines.forEach { diffResult.appendLine("- $it") }
//                    delta.target.lines.forEach { diffResult.appendLine("+ $it") }
//                }
//
//                DeltaType.EQUAL -> TODO()
//            }
//        }
//
//        return diffResult.toString().trimEnd()
//    }

    private fun formatYaml(map: Map<String, Any>): String {
        val writer = StringWriter()
        yaml.dump(map, writer)
        return writer.toString()
    }


//    fun addOrUpdateYamlConfig(
//        currentConfig: String,
//        newConfigMap: Map<String, Any>
//    ): String {
//        val currentMap: MutableMap<String, Any> = if (currentConfig.isNotBlank()) {
//            yaml.load(currentConfig) ?: mutableMapOf()
//        } else {
//            mutableMapOf()
//        }
//
//        // 合并配置
//        addOrUpdateYamlConfig(currentMap, newConfigMap)
//
//        val updatedYaml = yaml.dump(currentMap)
//        return updatedYaml
//    }

//    fun addOrUpdateYamlConfig(
//        currentMap: MutableMap<String, Any>,
//        newConfigMap: Map<String, Any>
//    ): MutableMap<String, Any> {
//        // 合并配置
//        deepMerge(currentMap, newConfigMap)
//        return currentMap
//    }
//
//    fun removeYamlConfig(
//        currentConfig: String,
//        keyPaths: List<String>
//    ): String {
//        val currentMap: MutableMap<String, Any> = yaml.load(currentConfig) ?: return ""
//        removeYamlConfig(currentMap, keyPaths)
//        val updatedYaml = yaml.dump(currentMap)
//        return updatedYaml
//    }

//    fun removeYamlConfig(
//        currentMap: MutableMap<String, Any>,
//        keyPaths: List<String>
//    ): MutableMap<String, Any> {
//
//        // 批量删除指定路径的键
//        keyPaths.forEach { path ->
//            removeKeyByPath(currentMap, path)
//        }
//        return currentMap
//    }

//    private fun removeKeyByPath(map: MutableMap<String, Any>, path: String): Boolean {
//        val keys = path.split(".")
//        return removeKeyByPathRecursive(map, keys, 0)
//    }

    private fun removeKeyByPathRecursive(currentMap: MutableMap<String, Any>, keys: List<String>, index: Int): Boolean {
        val key = keys[index]

        if (index == keys.size - 1) {
            // 到达最后一个key，删除这个key
            val removed = currentMap.remove(key) != null
            return removed
        } else {
            val nextLevel = currentMap[key]
            if (nextLevel is MutableMap<*, *>) {
                @Suppress("UNCHECKED_CAST")
                val nextMap = nextLevel as MutableMap<String, Any>
                val removed = removeKeyByPathRecursive(nextMap, keys, index + 1)
                // 删除后检查这个map是否为空，空的话也删除该key
                if (removed && nextMap.isEmpty()) {
                    currentMap.remove(key)
                }
                return removed
            }
        }
        return false
    }

    fun deepMerge(
        original: MutableMap<String, Any>,
        newMap: Map<String, Any>
    ) {
        for ((key, newValue) in newMap) {
            val oldValue = original[key]
            when {
                oldValue is Map<*, *> && newValue is Map<*, *> -> {
                    @Suppress("UNCHECKED_CAST")
                    deepMerge(
                        oldValue as MutableMap<String, Any>,
                        newValue as Map<String, Any>
                    )
                }

                oldValue is List<*> && newValue is List<*> -> {
                    // 合并列表：追加去重
                    val mergedList = (oldValue + newValue).distinct()
                    original[key] = mergedList
                }

                else -> {
                    original[key] = newValue
                }
            }
        }
    }

    @Suppress("UNCHECKED_CAST")
    fun deepCopy(map: Map<String, Any>): MutableMap<String, Any> {
        val result = mutableMapOf<String, Any>()
        for ((key, value) in map) {
            result[key] = when (value) {
                is Map<*, *> -> deepCopy(value as Map<String, Any>)
                is List<*> -> value.map {
                    if (it is Map<*, *>) deepCopy(it as Map<String, Any>) else it
                }.toMutableList()

                else -> value
            }
        }
        return result
    }

    fun diffYamlMap(oldYamlString: String, newYamlString: String): List<String> {
        val formattedOld = parseYamlStringToMap(oldYamlString)
        val formattedNew = parseYamlStringToMap(newYamlString)
        return diffYamlMap(formattedOld, formattedNew)
    }

    fun diffYamlMap(oldMap: Map<String, Any>, newMap: Map<String, Any>, prefix: String = ""): List<String> {
        val diffs = mutableListOf<String>()
        val allKeys = oldMap.keys union newMap.keys

        for (key in allKeys) {
            val oldVal = oldMap[key]
            val newVal = newMap[key]
            val fullKey = if (prefix.isEmpty()) key else "$prefix.$key"

            when {
                oldVal == null -> diffs.add("新增 $fullKey = $newVal")
                newVal == null -> diffs.add("删除 $fullKey (原值: $oldVal)")
                oldVal is Map<*, *> && newVal is Map<*, *> -> {
                    @Suppress("UNCHECKED_CAST")
                    diffs += diffYamlMap(oldVal as Map<String, Any>, newVal as Map<String, Any>, fullKey)
                }
                oldVal != newVal -> diffs.add("修改 $fullKey: $oldVal -> $newVal")
            }
        }
        return diffs
    }
}
